package com.yf.notify.modules.sms.providers.qcloud.service.impl;

import com.alibaba.fastjson.JSON;
import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.tencentcloudapi.common.profile.ClientProfile;
import com.tencentcloudapi.common.profile.HttpProfile;
import com.tencentcloudapi.sms.v20210111.SmsClient;
import com.tencentcloudapi.sms.v20210111.models.SendSmsRequest;
import com.tencentcloudapi.sms.v20210111.models.SendSmsResponse;
import com.tencentcloudapi.sms.v20210111.models.SendStatus;
import com.yf.ability.config.dto.CfgPropDTO;
import com.yf.ability.config.enums.ConfigType;
import com.yf.ability.config.enums.ProviderType;
import com.yf.ability.config.service.CfgPropService;
import com.yf.base.api.exception.ServiceException;
import com.yf.notify.modules.sms.providers.qcloud.config.QCloudSmsConfig;
import com.yf.notify.modules.sms.providers.qcloud.utils.MsgMap;
import com.yf.notify.modules.sms.service.SmsService;
import com.yf.notify.utils.ArrayUtils;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.LinkedHashMap;
import java.util.List;

/**
 * 腾讯云人脸识别实现
 * @author
 */
@Log4j2
@Service("qcloudSmsService")
public class QCloudSmsServiceImpl implements SmsService {

    @Autowired
    private CfgPropService cfgPropService;

    /**
     * 最大发送量
     */
    private static final int MAX_TO = 200;

    @Override
    public boolean sendSms(String templateId, String [] mobiles, LinkedHashMap<String,String> params) {


        // 获取短信配置
        CfgPropDTO dto = cfgPropService.detail(ConfigType.SMS, ProviderType.QCLOUD);
        QCloudSmsConfig conf = JSON.parseObject(dto.getData(), QCloudSmsConfig.class);

        if(conf == null || StringUtils.isBlank(conf.getSecretId()) || StringUtils.isBlank(conf.getSecretKey()) || StringUtils.isBlank(conf.getAppId())){
            throw new ServiceException("短信配置错误，请联系管理员！");
        }

        // 短信按顺序组装
        String [] arr = params.values().toArray(new String[0]);

        // 最多200个手机号码
        if(mobiles.length > MAX_TO){
            List<List<String>> list = ArrayUtils.split(mobiles, MAX_TO);
            boolean result = true;
            for(List<String> item: list){
                String [] subs = item.toArray(new String[0]);
                result = sendSms(conf, templateId, subs, arr);
                // 出错不发
                if(!result){
                    break;
                }
            }
            return result;
        }else{
            // 直接发送
            return sendSms(conf, templateId, mobiles, arr);
        }


    }

    /**
     * 发送短信
     * @param templateId
     * @param mobiles
     * @param params
     * @return
     */
    private boolean sendSms(QCloudSmsConfig conf, String templateId, String [] mobiles, String [] params) throws ServiceException {

        try{
            // 实例化一个认证对象，入参需要传入腾讯云账户secretId，secretKey,此处还需注意密钥对的保密
            // 密钥可前往https://console.cloud.tencent.com/cam/capi网站进行获取
            Credential cred = new Credential(conf.getSecretId(), conf.getSecretKey());
            // 实例化一个http选项，可选的，没有特殊需求可以跳过
            HttpProfile httpProfile = new HttpProfile();
            httpProfile.setEndpoint("sms.tencentcloudapi.com");
            // 实例化一个client选项，可选的，没有特殊需求可以跳过
            ClientProfile clientProfile = new ClientProfile();
            clientProfile.setHttpProfile(httpProfile);
            // 实例化要请求产品的client对象,clientProfile是可选的
            SmsClient client = new SmsClient(cred, "ap-guangzhou", clientProfile);
            // 实例化一个请求对象,每个接口都会对应一个request对象
            SendSmsRequest req = new SendSmsRequest();
            // 最多200个
            req.setPhoneNumberSet(mobiles);
            req.setSmsSdkAppId(conf.getAppId());
            req.setSignName(conf.getSign());
            req.setTemplateId(templateId);
            req.setTemplateParamSet(params);

            // 返回的resp是一个SendSmsResponse的实例，与请求对象对应
            SendSmsResponse resp = client.SendSms(req);
            // 输出json格式的字符串回包
            return this.parseResult(resp);
        } catch (TencentCloudSDKException e) {
            e.printStackTrace();
            throw new ServiceException(e.getMessage());
        }
    }

    /**
     * 处理结果
     * @param resp
     * @return
     */
    private boolean parseResult(SendSmsResponse resp){
        SendStatus [] status = resp.getSendStatusSet();
        for(SendStatus item: status){
            String code = item.getCode();
            if(!"ok".equalsIgnoreCase(code)){
                String msg = MsgMap.mapMsg(code);
                throw new ServiceException(msg);
            }
        }
        return true;
    }
}
